
#include <BPainter>
#include <BKeyEvent>
#include <BMouseEvent>
#include <BWidget>

#include <BEventFilter>
#include "member_BEventFilter.h"
#include "member_BObject.h"

using namespace BWE;

#define member					(*(member_BEventFilter*)_ptr)
#define member_allocate()		_ptr = new member_BEventFilter(this)
#define member_release()		delete (member_BEventFilter*)_ptr

BEventFilter::BEventFilter(BEventFilter* parent) : BObject()
{
	member_allocate();
	if (parent)
		parent->addChild(this);
}
BEventFilter::BEventFilter(const BString& name, BEventFilter* parent) : BObject(name)
{
	member_allocate();
	if (parent)
		parent->addChild(this);
}
BEventFilter::~BEventFilter()
{
	member_release();
	for (int i = 0; i < member.children.size(); i++)
	{
		BEventFilter* child = member.children[i];
		filter_member(child)->parent = 0;
	}
}

void BEventFilter::copy(const BEventFilter* other)
{
	object_member(this)->name = object_member(other)->name;

	for (int i = 0; i < filter_member(other)->children.size(); i++)
	{
		BEventFilter* filter = filter_member(other)->children[i]->clone();
		member.children.append(filter);
	}
}
BEventFilter* BEventFilter::clone() const
{
	BEventFilter* filter = new BEventFilter();
	filter->copy(this);
	return filter;
}

BWidget* BEventFilter::host()
{
	return member.host;
}
const BWidget* BEventFilter::host() const
{
	return member.host;
}

bool BEventFilter::fresh() const
{
	if (member.host)
	{
		member.host->fresh();
		return true;
	}
	return false;
}

void BEventFilter::setParent(BEventFilter* parent)
{
	if (member.parent != parent && parent != this)
	{
		BHolder<BEventFilter> holder;
		if (member.parent)
		{
			holder = this;
			member.parent->removeChild(this);
		}
		if (parent)
		{
			parent->addChild(this);
			holder = 0;
		}
	}
}
const BEventFilter* BEventFilter::parent() const
{
	return member.parent;
}
BEventFilter* BEventFilter::parent()
{
	return member.parent;
}

bool BEventFilter::addChild(BEventFilter* child)
{
	if (!child && child == this)
		return true;
	if (filter_member(child)->parent == this)
		return true;
	if (member.children.append(child))
	{
		if (BEventFilter* parent = filter_member(child)->parent)
			parent->removeChild(child);
		filter_member(child)->parent = this;
		filter_member(child)->setWidget(member.host);
		object_member(child)->emit(Signal_ParentChanged, BValue(this, true));
		this->emit(Signal_Insert, BValue(child, this));
		this->fresh();
		return true;
	}
	return false;
}
bool BEventFilter::insertChild(int pos, BEventFilter* child)
{
	if (!child && child == this)
		return false;
	if (filter_member(child)->parent == this)
	{
		int index = member.children.find(child);
		return member.children.move(index, pos);
	}
	if (member.children.insert(pos, child))
	{
		if (BEventFilter* parent = filter_member(child)->parent)
			parent->removeChild(child);
		filter_member(child)->parent = this;
		filter_member(child)->setWidget(member.host);
		object_member(child)->emit(Signal_ParentChanged, BValue(this, true));
		this->emit(Signal_Insert, BValue(child, this));
		this->fresh();
		return true;
	}
	return false;
}
bool BEventFilter::removeChild(BEventFilter* child)
{
	if (!child || child == this)
		return false;
	if (filter_member(child)->parent != this)
		return false;
	BHolder<BEventFilter> holder(child);
	filter_member(child)->parent = 0;
	filter_member(child)->setWidget(0);
	member.children.remove(child);
	object_member(child)->emit(Signal_ParentChanged);
	this->emit(Signal_Remove, BValue(child, this));
	this->fresh();
	return true;
}
bool BEventFilter::clearChildren()
{
	if (member.children.size())
	{
		while (BEventFilterHolder child = member.children.last())
		{
			this->removeChild(child);
		}
		this->emit(Signal_Clear);
		return true;
	}
	return false;
}

bool BEventFilter::contain(BEventFilter* child)
{
	return member.children.contain(child);
}
bool BEventFilter::contain(const BString& name) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i]->name() == name)
			return true;
	}
	return false;
}

int BEventFilter::childCount() const
{
	return member.children.size();
}
BEventFilter* BEventFilter::child(int index) const
{
	return member.children(index);
}
BEventFilter* BEventFilter::child(const BString& name) const
{
	for (int i = 0; i < member.children.size(); i++)
	{
		if (member.children[i]->name() == name)
			return member.children[i];
	}
	return 0;
}

int BEventFilter::index() const
{
	if (BEventFilter* parent = member.parent)
	{
		BEventFilterHolderArray& children = filter_member(parent)->children;
		return children.find(this);
	}
	return -1;
}
bool BEventFilter::above(const BEventFilter* other) const
{
	if (!other)
		return false;
	BEventFilter* parent = filter_member(other)->parent;
	while (parent)
	{
		if (parent == this)
			return true;
		parent = filter_member(parent)->parent;
	}
	return false;
}
bool BEventFilter::under(const BEventFilter* other) const
{
	BEventFilter* parent = member.parent;
	while (parent)
	{
		if (parent == other)
			return true;
		parent = filter_member(parent)->parent;
	}
	return false;
}

void BEventFilter::raise()
{
	if (BEventFilter* parent = member.parent)
	{
		BEventFilterHolderArray& children = filter_member(parent)->children;
		int pos = children.find(this);
		if (children.move(pos, 0))
			this->fresh();
	}
}
void BEventFilter::lower()
{
	if (BEventFilter* parent = member.parent)
	{
		BEventFilterHolderArray& children = filter_member(parent)->children;
		int pos = children.find(this);
		if (children.move(pos, children.size() - 1))
			this->fresh();
	}
}
bool BEventFilter::detach()
{
	if (member.parent)
	{
		member.parent->removeChild(this);
		return true;
	}
	if (BWidget* host = member.host)
	{
		host->setEventFilter(0);
		return true;
	}
	return false;
}

void BEventFilter::attached(BWidget* host)
{

}
void BEventFilter::detached(BWidget* host)
{

}

void BEventFilter::event(const BEvent& event)
{
	if (!member.host)
		return;

	for (int i = member.children.size() - 1; i >= 0; i--)
	{
		BEventFilter* child = member.children[i];
		if (!child->enabled())
			continue;
		child->event(event);
		if (event.accepted())
			return;
	}

	switch (event.type())
	{
	case Event_Show:
		this->showEvent(event);
		break;
	case Event_Hide:
		this->hideEvent(event);
		break;
	case Event_Close:
		this->closeEvent(event);
		break;
	case Event_Move:
		this->moveEvent(event);
		break;
	case Event_Resize:
		this->resizeEvent(event);
		break;
	case Event_Adjust:
		this->adjustEvent(event);
		break;
	case Event_Update:
		this->updateEvent(event);
		break;
	case Event_Style:
		this->styleEvent(event);
		break;
	case Event_Fresh:
		this->freshEvent(event);
		break;
	case Event_Paint:
		this->paintEvent(event);
		break;
	case Event_Active:
		this->activeEvent(event);
		break;
	case Event_Hover:
		this->hoverEvent(event);
		break;
	case Event_Focus:
		this->focusEvent(event);
		break;
	case Event_Input:
		this->inputEvent(event);
		break;
	case Event_KeyPress:
		this->keyPressEvent((const BKeyEvent&)event);
		break;
	case Event_KeyRelease:
		this->keyReleaseEvent((const BKeyEvent&)event);
		break;
	case Event_MouseEnter:
		this->mouseEnterEvent((const BMouseEvent&)event);
		break;
	case Event_MouseLeave:
		this->mouseLeaveEvent((const BMouseEvent&)event);
		break;
	case Event_MouseMove:
		this->mouseMoveEvent((const BMouseEvent&)event);
		break;
	case Event_MousePress:
		this->mousePressEvent((const BMouseEvent&)event);
		break;
	case Event_MouseRelease:
		this->mouseReleaseEvent((const BMouseEvent&)event);
		break;
	case Event_MouseClick:
		this->mouseClickEvent((const BMouseEvent&)event);
		break;
	case Event_DoubleClick:
		this->mouseDoubleClickEvent((const BMouseEvent&)event);
		break;
	case Event_MouseWheel:
		this->mouseWheelEvent((const BMouseEvent&)event);
		break;
	case Event_DragEnter:
		this->dragEnterEvent((const BMouseEvent&)event);
		break;
	case Event_DragLeave:
		this->dragLeaveEvent((const BMouseEvent&)event);
		break;
	case Event_DragMove:
		this->dragMoveEvent((const BMouseEvent&)event);
		break;
	case Event_DragDrop:
		this->dragDropEvent((const BMouseEvent&)event);
		break;
	default:
		break;
	}
}

void BEventFilter::showEvent(const BEvent& event)
{

}
void BEventFilter::hideEvent(const BEvent& event)
{

}
void BEventFilter::closeEvent(const BEvent& event)
{

}

void BEventFilter::moveEvent(const BEvent& event)
{

}
void BEventFilter::resizeEvent(const BEvent& event)
{

}
void BEventFilter::updateEvent(const BEvent& event)
{

}
void BEventFilter::adjustEvent(const BEvent& event)
{

}

void BEventFilter::styleEvent(const BEvent& event)
{

}
void BEventFilter::freshEvent(const BEvent& event)
{

}
void BEventFilter::paintEvent(const BEvent& event)
{

}

void BEventFilter::activeEvent(const BEvent& event)
{

}
void BEventFilter::hoverEvent(const BEvent& event)
{

}
void BEventFilter::focusEvent(const BEvent& event)
{

}
void BEventFilter::inputEvent(const BEvent& event)
{

}

void BEventFilter::keyPressEvent(const BKeyEvent& keyEvent)
{

}
void BEventFilter::keyReleaseEvent(const BKeyEvent& keyEvent)
{

}

void BEventFilter::mouseEnterEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::mouseLeaveEvent(const BMouseEvent& mouseEvent)
{

}

void BEventFilter::mousePressEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::mouseReleaseEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::mouseMoveEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::mouseWheelEvent(const BMouseEvent& mouseEvent)
{

}

void BEventFilter::mouseClickEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::mouseDoubleClickEvent(const BMouseEvent& mouseEvent)
{

}

void BEventFilter::dragEnterEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::dragLeaveEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::dragMoveEvent(const BMouseEvent& mouseEvent)
{

}
void BEventFilter::dragDropEvent(const BMouseEvent& mouseEvent)
{

}
